import logging

from ihome.utils.views import LoginRequiredMixin
from users.models import User
logger = logging.getLogger('django')
import random
import json
import re
from django import http
from django_redis import get_redis_connection
from django.views import View
from django.http import HttpResponse, JsonResponse
from ihome.libs.captcha.captcha import captcha
from celery_tasks.sms.tasks import ccp_send_sms_code
from django.contrib.auth import logout
from django.contrib.auth import login, authenticate


class ImageCodeView(View):
    '''返回图形验证码的类视图'''

    def get(self, request):
        cur = request.GET.get('cur')

        pre = request.GET.get('pre')

        text, image = captcha.generate_captcha()

        redis_conn = get_redis_connection('verify_code')

        redis_conn.setex('img_%s' % cur, 300, text)

        return HttpResponse(image)


class SMSCodeView(View):

    def post(self, request):

        dict = json.loads(request.body.decode())

        mobile = dict.get('mobile')

        redis_conn = get_redis_connection('verify_code')
        send_flag = redis_conn.get('send_flag_%s' % mobile)
        if send_flag:
            return http.JsonResponse({'errno': 4201,
                                      'errmsg': '非法请求或请求次数受限'})

        image_code_client = dict.get('text')
        uuid = dict.get('id')

        if not all([image_code_client, uuid]):
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数错误'})

        image_code_server = redis_conn.get('img_%s' % uuid)
        if image_code_server is None:
            return http.JsonResponse({'errno': 4201,
                                      'errmsg': '非法请求或请求次数受限'})

        try:
            redis_conn.delete('img_%s' % uuid)
        except Exception as e:
            logger.error(e)

        image_code_server = image_code_server.decode()
        if image_code_client.lower() != image_code_server.lower():
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数错误'})

        sms_code = '%06d' % random.randint(0, 999999)
        logger.info(sms_code)

        # redis_conn.setex('send_flag_%s' % mobile, 60, 1)

        # 创建管道对象:
        pl = redis_conn.pipeline()

        # redis_conn.setex('sms_%s' % mobile, 300, sms_code)
        pl.setex('sms_%s' % mobile, 300, sms_code)

        # redis_conn.setex('send_flag_%s' % mobile, 60, 1)
        pl.setex('send_flag_%s' % mobile, 60, 1)

        # 执行管道:
        pl.execute()

        # 原来的写法:
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)

        # 改为现在的写法, 注意: 这里的函数,调用的时候需要加: .delay()
        # ccp_send_sms_code.delay(mobile, sms_code)

        return http.JsonResponse({'errno': 0,
                                  'errmsg': '发送短信成功'})

class RegisterView(View):

    def post(self, request):
        '''接收参数, 保存到数据库'''
        # 1.接收参数
        dict = json.loads(request.body.decode())
        mobile = dict.get('mobile')
        password = dict.get('password')
        sms_code_client = dict.get('phonecode')

        # 2.校验(整体)
        if not all([password, mobile, sms_code_client]):
            return http.JsonResponse({'errno': 4201,
                                      'errmsg': '非法请求或请求次数受限'})

        # 3.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数有错误'})

        # 4.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数有错误'})

        # # 5.sms_code检验 (链接redis数据库)
        # redis_conn = get_redis_connection('verify_code')
        #
        # # 9.从redis中取值
        # sms_code_server = redis_conn.get('sms_%s' % mobile)
        #
        # # 10.判断该值是否存在
        # if not sms_code_server:
        #     return http.JsonResponse({'errno': 4001,
        #                               'errmsg': '数据库查询错误'})
        # # 11.把redis中取得值和前端发的值对比
        # if sms_code_client != sms_code_server.decode():
        #     return http.JsonResponse({'errno': 4004,
        #                               'errmsg': '数据错误'})

        # 12.保存到数据库 (username password mobile)
        try:
            user = User.objects.create_user(username=mobile,
                                            password=password,
                                            mobile=mobile)
        except Exception as e:

            return http.JsonResponse({'errno': 400,
                                      'errmsg': '保存到数据库出错'})
        login(request, user)

        # 生成响应对象
        response = http.JsonResponse({'errno': 0,
                                      'errmsg': 'ok'})

        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username',
                            user.username,
                            max_age=3600 * 24 * 14)

        # 返回响应结果
        return response

class LoginLogoutView(View):

    def post(self, request):
        '''实现登录接口'''
        # 接收参数
        dict = json.loads(request.body.decode())

        password = dict.get('password')
        mobile = dict.get('mobile')

        if not all([mobile, password]):
            return http.JsonResponse({'errno': 4201,
                                      'errmsg': '非法请求或请求次数受限'})

        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数有错误'})

        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({'errno': 4103,
                                      'errmsg': '参数有错误'})

        # 验证是否能够登录
        user = authenticate(username=mobile,
                            mobile=mobile,
                            password=password)

        # 判断是否为空,如果为空,返回
        if user is None:
            return http.JsonResponse({'errno': 4106,
                                      'errmsg': '密码错误'})


        # 状态保持
        login(request,user)

        # 设置为两周有效
        request.session.set_expiry(None)


        # 生成响应对象
        response = http.JsonResponse({'errno': 0,
                                      'errmsg': 'ok'})

        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        response.set_cookie('username',user.username,
                            max_age=3600 * 24 * 14)

        # 返回响应结果
        return response

    def get(self, request):

        # 判断用户是否登录:
        if request.user.is_authenticated:

            data = {'name':request.user.username,
                    'user_id':request.user.id}

            return JsonResponse({'errno': 0,
                                 'errmsg': 'ok',
                                 'data': data})
        else:

            return JsonResponse({'errno': 4101,
                                 'errmsg': '用户未登录'})

    def delete(self, request):
        """实现退出登录逻辑"""

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = http.JsonResponse({'errno':0,
                                      'errmsg':'已登出'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response




